package spacegame.main;

import java.util.List;

import org.andengine.engine.Engine;
import org.andengine.engine.FixedStepEngine;
import org.andengine.engine.LimitedFPSEngine;
import org.andengine.engine.camera.BoundCamera;
import org.andengine.engine.camera.hud.controls.AnalogOnScreenControl;
import org.andengine.engine.camera.hud.controls.BaseOnScreenControl;
import org.andengine.engine.camera.hud.controls.AnalogOnScreenControl.IAnalogOnScreenControlListener;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.scene.background.RepeatingSpriteBackground;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.extension.physics.box2d.FixedStepPhysicsWorld;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.extension.physics.box2d.util.Vector2Pool;
import org.andengine.input.sensor.acceleration.AccelerationData;
import org.andengine.input.sensor.acceleration.IAccelerationListener;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import spacegame.interfaces.ISpaceObject;
import spacegame.interfaces.ISpaceWorldContainer;
import spacegame.model.SpaceObjectCollection;
import spacegame.model.SpacePhysicsWorld;
import spacegame.model.SpaceShipItem;
import spacegame.resources.ResourceFactory;
import spacegame.resources.ResourceFactory.TextureType;

import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.SensorManager;
import android.opengl.GLES20;
import android.util.Log;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
//import android.util.Log;
/**
 *
 * @author Muiota Betarho
 * @since 18:47:08 - 15.09.2012
 */
public class MainActivity extends SimpleBaseGameActivity implements IAccelerationListener, IOnSceneTouchListener, ISpaceWorldContainer {
	// ===========================================================
	// Constants
	// ===========================================================

	protected static final int m_worldSize = 128;
	protected static final int CAMERA_WIDTH = 480;
	protected static final int CAMERA_HEIGHT = 320;

	private Scene m_scene;  //Сцена
	private BoundCamera m_mainCamera; //Камера
	private SpacePhysicsWorld m_physicsWorld; //Физический мир
	

	private ITextureRegion m_onScreenControlBaseTextureRegion;
	private ITextureRegion m_onScreenControlKnobTextureRegion;

	private RepeatingSpriteBackground m_repeatingBackground;
	

	private ResourceFactory m_resorceFactory;





	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	public EngineOptions onCreateEngineOptions() {
		//Toast.makeText(this, "Touch the screen to add objects.", Toast.LENGTH_LONG).show();

		//this.m_camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		//-CAMERA_WIDTH*64, -CAMERA_HEIGHT*64, CAMERA_WIDTH*129, 2
		//this.mBoundChaseCamera = new BoundCamera(0, 0, CAMERA_WIDTH , CAMERA_HEIGHT , 0, CAMERA_WIDTH, 0, CAMERA_HEIGHT)
		this.m_mainCamera = new SpaceCamera(0 , 0, CAMERA_WIDTH , CAMERA_HEIGHT);
		return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), m_mainCamera);
	}

//	@Override
//	public Engine onCreateEngine(final EngineOptions pEngineOptions) {
//		return new FixedStepEngine(pEngineOptions, 60);
//	}

	
	@Override
	public void onCreateResources() {
		
		m_resorceFactory = new ResourceFactory(this, m_worldSize);
		
	
		m_onScreenControlBaseTextureRegion= m_resorceFactory.TryGetTexture(TextureType.ControlBaseTexture);
		m_onScreenControlKnobTextureRegion= m_resorceFactory.TryGetTexture(TextureType.ControlKnobTexture);
		m_repeatingBackground = m_resorceFactory.GetRepeatingBackground();		
	}

	
	@Override
	public Scene onCreateScene() {
		//this.mEngine.registerUpdateHandler(new FPSLogger());

		this.m_scene = new Scene();

		this.m_scene.setBackground(new Background(0, 0, 0));
		this.m_scene.setOnSceneTouchListener(this);

		
		this.m_physicsWorld = new SpacePhysicsWorld( new Vector2(0, 0), false );
	
		final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
		//Bounds of world
		final Rectangle _ground = new Rectangle(-CAMERA_WIDTH*m_worldSize, CAMERA_HEIGHT*(m_worldSize+1) - 2, CAMERA_WIDTH*(m_worldSize*2+1), 2, vertexBufferObjectManager);
		final Rectangle _roof = new Rectangle(-CAMERA_WIDTH*m_worldSize, -CAMERA_HEIGHT*m_worldSize, CAMERA_WIDTH*(m_worldSize*2+1), 2, vertexBufferObjectManager);
		final Rectangle _left = new Rectangle(-CAMERA_WIDTH*m_worldSize, -CAMERA_HEIGHT*m_worldSize, 2, CAMERA_HEIGHT*(m_worldSize*2+1), vertexBufferObjectManager);
		final Rectangle _right = new Rectangle(CAMERA_WIDTH*(m_worldSize+1) - 2, - CAMERA_HEIGHT*m_worldSize, 2, CAMERA_HEIGHT*(m_worldSize*2+1), vertexBufferObjectManager);

		final FixtureDef _wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
		PhysicsFactory.createBoxBody(this.m_physicsWorld, _ground, BodyType.StaticBody, _wallFixtureDef);
		PhysicsFactory.createBoxBody(this.m_physicsWorld, _roof, BodyType.StaticBody, _wallFixtureDef);
		PhysicsFactory.createBoxBody(this.m_physicsWorld, _left, BodyType.StaticBody, _wallFixtureDef);
		PhysicsFactory.createBoxBody(this.m_physicsWorld, _right, BodyType.StaticBody, _wallFixtureDef);

		this.m_scene.attachChild(_ground);
		this.m_scene.attachChild(_roof);
		this.m_scene.attachChild(_left);
		this.m_scene.attachChild(_right);

		this.m_scene.registerUpdateHandler(this.m_physicsWorld);

		//Set scene gravity
		final Vector2 _gravity = Vector2Pool.obtain(0, 0);
		this.m_physicsWorld.setGravity(_gravity);
		Vector2Pool.recycle(_gravity);
		
			 
		Sprite repeatingSprite = this.m_repeatingBackground.getSprite();
		repeatingSprite.setPosition(-CAMERA_WIDTH*m_worldSize, -CAMERA_HEIGHT*m_worldSize);
		repeatingSprite.setChildrenIgnoreUpdate(true);
		repeatingSprite.setIgnoreUpdate(true);
		this.m_scene.attachChild(repeatingSprite);
		
		
		this.m_physicsWorld.Init(this, m_resorceFactory);
		this.m_physicsWorld.CreateScene();
		
		this.initOnScreenControls();
	
		

		
	
		
		this.m_mainCamera.setBoundsEnabled(false);
		
		
		//this.mBoundChaseCamera.set(0, 0, CAMERA_WIDTH , CAMERA_HEIGHT);
		return this.m_scene;
	}

	
	
	
	@Override
	public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
		if(this.m_physicsWorld != null) {
			if(pSceneTouchEvent.isActionDown()) {
				this.addFace(pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
				return true;
			}
		}
		return false;
	}

	@Override
	public void onAccelerationAccuracyChanged(final AccelerationData pAccelerationData) {

	}

	@Override
	public void onAccelerationChanged(final AccelerationData pAccelerationData) {
		
	}

	@Override
	public void onResumeGame() {
		super.onResumeGame();

		this.enableAccelerationSensor(this);
	}

	@Override
	public void onPauseGame() {
		super.onPauseGame();
		this.disableAccelerationSensor();
	}

	// ===========================================================
	// Methods
	// ===========================================================

	private void addFace(final float pX, final float pY) {
		m_physicsWorld.CreateSpaceObject(pX, pY);
		
	}


	
	//Make screen controls
	@SuppressLint({ "FloatMath", "FloatMath" })
	private void initOnScreenControls() {
		final AnalogOnScreenControl analogOnScreenControl = new AnalogOnScreenControl(0, 
				CAMERA_HEIGHT - this.m_onScreenControlBaseTextureRegion.getHeight(), 
				this.m_mainCamera, this.m_onScreenControlBaseTextureRegion, 
				this.m_onScreenControlKnobTextureRegion, 0.1f, 
				this.getVertexBufferObjectManager(), new IAnalogOnScreenControlListener() {
			@Override
			public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
				//final Body carBody = RacerGameActivity.this.mCarBody;
			
				
		 if (m_physicsWorld != null)
				m_physicsWorld.ApplyEngineForce(pValueX, pValueY);					
		
		//	m_testbody.setLinearVelocity (velocity);}
				//	carBody.setLinearVelocity(velocity);
			//	Vector2Pool.recycle(_velocity);

			//	final float _rotationInRad = (float)Math.atan2(-pValueX, pValueY);
			//	carBody.setTransform(carBody.getWorldCenter(), rotationInRad);

			//	RacerGameActivity.this.mCar.setRotation(MathUtils.radToDeg(rotationInRad));
			}

			@Override
			public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
				/* Nothing. */
			}
		});
		analogOnScreenControl.getControlBase().setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
		analogOnScreenControl.getControlBase().setAlpha(0.2f);
		analogOnScreenControl.getControlKnob() .setAlpha(0.3f);
		//		analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		//		analogOnScreenControl.getControlBase().setScale(0.75f);
		//		analogOnScreenControl.getControlKnob().setScale(0.75f);
		analogOnScreenControl.refreshControlKnobPosition();

		this.m_scene.setChildScene(analogOnScreenControl);
	}
	

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================

	public Scene GetCurrentScene() {
		return m_scene;
	}

	public BoundCamera GetCurrentCamera() {
		return m_mainCamera;
	}

	public PhysicsWorld GetCurrentPhysicsWorld() {
		return m_physicsWorld;
	}

	
	public Engine GetCurrentEngine() {
		return mEngine;
	}

	@Override
	public Context GetContext() {	
		return this;
	}


}
